#include "oled.h"
#include <stdio.h>
#include <string.h>
#include "../gh_main.h"

uint8_t oled_read[20] = {0};
oled_recv_get sure_oled={0};
int now_id = 0;

uint8_t oled_recv[UART_DATA_RECV_SIZE] = {0};
uart_buffer_config_t oled_buffer_config = {.rx_buffer = oled_recv, .rx_buffer_size = UART_DATA_RECV_SIZE};

//向oled发送命令
int oled_write(unsigned char *recv, int length) {
    int result = uapi_uart_write(CONFIG_OLED_UART_BUS, recv, length, 50);
    // osal_printk("Sent: %s (length=%d, result=%d)\r\n", recv, length, result);
    osal_mdelay(50); // 增加延时时间
    return result;
}

// 根据解析的命令类型调用不同的函数
static void process_parsed_data(oled_recv_get* recv)
{
    if (!recv->valid) return;
    
    printf("Command: 0x%02X\r\n", recv->cmd);
    
    // 根据命令ID处理数据
    switch (recv->cmd) {
        case CMD_ID:
            printf("Received CMD_ID (0x00)\r\n");
            printf("id:%d\r\n",recv->data);
            now_id = recv->data;
            set_oled_iddata(now_id);

            // 处理ID命令
            break;
        case CMD_BEEP:
            printf("Received CMD_BEEP (0x01)\r\n");
            // 处理蜂鸣器命令
            break;
        case CMD_OTHER:
            printf("Received CMD_OTHER (0x02)\r\n");
            // 处理其他命令
            break;
        case CMD_CON:
            set_id_con(get_Con(),recv);
            //处理控制命令
            break;
        default:
            printf("Unknown command: 0x%02X\r\n", recv->cmd);
            break;
    }
}

//解析uart数据包
static void parse_uart_packet(oled_recv_get* recv)
{
    // 初始化解析结果
    recv->cmd = CMD_NONE;
    recv->valid = false;
    
    // 检查长度是否足够（至少包含帧头、数据类型、数值、帧尾）
    if (recv->recv_len < 5) {  // 修正：现在最小长度为5字节
        printf("Packet too short\r\n");
        return;
    }
    
    // 查找帧头 55 01
    uint16_t header_pos = 0;
    while (header_pos < recv->recv_len - 1) {
        if (recv->recv[header_pos] == 0x55 && recv->recv[header_pos + 1] == 0x01) {
            break;
        }
        header_pos++;
    }
    
    // 如果未找到帧头
    if (header_pos >= recv->recv_len - 1) {
        printf("Header not found\r\n");
        return;
    }
    
    // 检查帧尾 0D 0A
    uint16_t tail_pos = header_pos + 3;  // 从数值字节之后开始查找
    while (tail_pos < recv->recv_len - 1) {
        if (recv->recv[tail_pos] == 0x0D && recv->recv[tail_pos + 1] == 0x0A) {
            break;
        }
        tail_pos++;
    }
    
    // 如果未找到帧尾
    if (tail_pos >= recv->recv_len - 1) {
        printf("Tail not found\r\n");
        return;
    }
    
    // 提取数据类型和数值
    if (header_pos + 3 <= tail_pos) {
        uint8_t data_type = recv->recv[header_pos + 2];
        uint8_t value = recv->recv[header_pos + 3];
        uint8_t contrle_cmd_a = recv->recv[header_pos + 4];
        uint8_t contrle_cmd_s = recv->recv[header_pos + 5];
        recv->cmd = data_type;//控制类型
        recv->data = value;//设备id
        recv->con[0] = contrle_cmd_a;//控制外设
        recv->con[1] = contrle_cmd_s;//控制状态

    } else {
        printf("No data bytes\r\n");
        return;
    }
    
    // 标记数据包有效
    recv->valid = true;
    
    // 处理解析结果
    process_parsed_data(recv);
}


// 1,Hum:23.1,Tem:25.2,Lig:90,SoilHum:66,over


void handle_data(char* data, char* result) {
    char chuli[10] = {0};
    // 找到小数点的位置
    char* dot = strchr(data, '.');
    if (dot != NULL) {
        // 截取小数点前的部分
        strncpy(chuli, data, dot - data);
        // 截取小数点后的两位
        strncpy(chuli + strlen(chuli), dot + 1, 2);
    } else {
        // 如果没有小数点，直接复制
        strcpy(chuli, data);
    }
    // 补充到4位整数
    while (strlen(chuli) < 4) {
        strcat(chuli, "0");
    }
    strcpy(result, chuli);
}

//设置当前显示的数据
void set_oled_data(SensorData* data) {
    unsigned char buff[64] = {0};  // 缓冲区
    int len = 0;
    char h_processed[5] = {0};
    char t_processed[5] = {0};
    char int_buffer[10] = {0};

    handle_data(data->humidity, h_processed);
    handle_data(data->temperature, t_processed);

    // 湿度(%)
    len = sprintf((char*)buff, "data.x0.val=%s\xff\xff\xff", h_processed);
    if (oled_write(buff, len) != len) {
        osal_printk("Error sending humidity data\r\n");
    }

    // 温度(°C)
    len = sprintf((char*)buff, "data.x1.val=%s\xff\xff\xff", t_processed);
    if (oled_write(buff, len) != len) {
        osal_printk("Error sending temperature data\r\n");
    }
    
    // 紫外线(强度) - 转换为整数
    float uv_val = atof(data->uv);
    int uv_int = (int)uv_val;
    sprintf(int_buffer, "%d", uv_int);
    len = sprintf((char*)buff, "data.n3.val=%s\xff\xff\xff", int_buffer);
    if (oled_write(buff, len) != len) {
        osal_printk("Error sending UV data\r\n");
    }

    // CO2 - 转换为整数
    float co2_val = atof(data->co2);
    int co2_int = (int)co2_val;
    sprintf(int_buffer, "%d", co2_int);
    len = sprintf((char*)buff, "data.n2.val=%s\xff\xff\xff", int_buffer);
    if (oled_write(buff, len) != len) {
        osal_printk("Error sending CO2 data\r\n");
    }

    // 降雨量 - 转换为整数
    float rain_val = atof(data->rain);
    int rain_int = (int)rain_val;
    sprintf(int_buffer, "%d", rain_int);
    len = sprintf((char*)buff, "data.n4.val=%s\xff\xff\xff", int_buffer);
    if (oled_write(buff, len) != len) {
        osal_printk("Error sending rainfall data\r\n");
    }

    // 土壤湿度 - 转换为整数
    float soil_val = atof(data->soilHum);
    int soil_int = (int)soil_val;
    sprintf(int_buffer, "%d", soil_int);
    len = sprintf((char*)buff, "data.n1.val=%s\xff\xff\xff", int_buffer);
    if (oled_write(buff, len) != len) {
        osal_printk("Error sending soil humidity data\r\n");
    }

    // 光照强度 - 转换为整数
    float lig_val = atof(data->ligBuffer);
    int lig_int = (int)lig_val;
    sprintf(int_buffer, "%d", lig_int);
    len = sprintf((char*)buff, "data.n0.val=%s\xff\xff\xff", int_buffer);
    if (oled_write(buff, len) != len) {
        osal_printk("Error sending light data\r\n");
    }
}

//设置oled上面的当前节点控制状态
void set_oled_con(ControlState* data) {
    unsigned char buff[64] = {0};  // 缓冲区
    int len = 0;

    osal_printk("set_oled_con\r\n");

    len = sprintf((char*)buff, "control.bt0.val=%s\xff\xff\xff", data->fanFlag[0]=='1'?"0":"1");
    if (oled_write(buff, len) != len) {
    }

    len = sprintf((char*)buff, "control.bt1.val=%s\xff\xff\xff", data->waterFlag[0]=='1'?"0":"1");
    if (oled_write(buff, len) != len) {
    }
    
    len = sprintf((char*)buff, "control.bt2.val=%s\xff\xff\xff", data->sunFlag[0]=='1'?"0":"1");
    if (oled_write(buff, len) != len) {
    }

}

//设置指定id的控制状态
void set_id_con(ControlState* data,oled_recv_get* recv) {
    if (data == NULL) {
        osal_printk("Invalid ControlState pointer in set_id_con\r\n");
        return;
    }

    // unsigned char buff [128] = {0}; // 缓冲区，预留足够空间
    // int len = 0;
    osal_printk("SET CON:%s\r\n",data->id);//打印控制的调试信息
    switch (recv->con[0])
    {
    case 0://风扇
        if(recv->con[1]==1)
            strcpy(data->fanFlag, "0");
        else if(recv->con[1]==2)
            strcpy(data->fanFlag, "1");
        break;
    case 1://灌溉
        if(recv->con[1]==1)
            strcpy(data->waterFlag, "0");
        else if(recv->con[1]==2)
            strcpy(data->waterFlag, "1");
        break;
    case 2://光照
        if(recv->con[1]==1)
            strcpy(data->sunFlag, "0");
        else if(recv->con[1]==2)
            strcpy(data->sunFlag, "1");
        break;
    default:
        break;
    }

    // // 按照格式拼接数据：idfF:fanFlag,wF:waterFlag,sF:sunFlag,swF:switchFlag,r:colorNum [0],g:colorNum [1],b:colorNum [2],
    //     // 注意：示例中的 "1fF" 应为 "idfF" 的缩写，这里按实际字段对应关系拼接

    //     len = sprintf ((char*) buff,
    //     SEND_CON,
    //     , data->id
    //     , data->fanFlag
    //     , data->waterFlag
    //     , data->sunFlag
    //     , data->switchFlag
    //     , data->colorNum [0]
    //     , data->colorNum [1]
    //     , data->colorNum [2]
    //     );
    char output[128] = {0};
    
    build_message(data,output,sizeof(output));

    // 发送拼接好的数据到节点
    send_data_to_sle(output);
}

// void switch_page(enum PAGE goal){
//     unsigned char buff[20] = {0};

//     switch (goal)
//     {
//     case START:
//         sprintf((char*)buff, "page start\xff\xff\xff");
//         break;
//     case DATA:
//         sprintf((char*)buff, "page data\xff\xff\xff");
//         break;
//     case NAVIGATION:
//         sprintf((char*)buff, "page navigation\xff\xff\xff");
//         break;
//     case CONTROL:
//         sprintf((char*)buff, "page control\xff\xff\xff");
//         break;
//     default:
//         break;
//     }

//     oled_write(buff);
// }

//回调函数
void oled_read_handler(const void *buffer, uint16_t length, bool error)
{
    unused(error);
    if (buffer == NULL || length == 0) {
        return;
    }
    osal_printk("oled_read_data:%s\r\n",buffer);//调试信息
    
    sure_oled.recv_len = 0;
    memset(sure_oled.recv, 0, sizeof(sure_oled.recv));
    memcpy(sure_oled.recv, buffer, length);
    sure_oled.recv_len = length;//对数据进行简单处理后开始解析
    parse_uart_packet(&sure_oled);//解析命令
    // osal_printk("oled:%s\r\n",oled_read);
}

void oled_init(){
    // oled串口初始化
    uart_gpio_init(CONFIG_OLED_UART_BUS,CONFIG_OLED_TXD_PIN,CONFIG_OLED_RXD_PIN);
    // 对 UART 进行初始化配置
    uart_init_config(CONFIG_OLED_UART_BUS,CONFIG_OLED_TXD_PIN,CONFIG_OLED_RXD_PIN,&oled_buffer_config);
    uapi_uart_register_rx_callback(CONFIG_OLED_UART_BUS, UART_RX_CONDITION_MASK_IDLE, 10, oled_read_handler);

}